package com.jews.mongodb.support;

import com.google.common.base.Preconditions;
import com.jews.common.validator.CreateGroup;
import io.vavr.control.Try;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.repository.CrudRepository;

import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 创建一个实体对象操作
 *
 * @author JewsChen
 * @title: EntityCreator
 * @date 2022/11/28 23:26
 */
@Slf4j
public class EntityCreator<T, ID>
        extends BaseEntityOperation
        implements Create<T>, UpdateHandler<T>, Executor<T> {

    private final CrudRepository<T, ID> repository;
    private T entity;
    private Consumer<T> successHook = t -> log.info("save success");
    private Consumer<? super Throwable> errorHook = Throwable::printStackTrace;

    public EntityCreator(CrudRepository<T, ID> repository) {
        this.repository = repository;
    }

    @Override
    public UpdateHandler<T> create(Supplier<T> supplier) {
        this.entity = supplier.get();
        return this;
    }

    @Override
    public Executor<T> update(Consumer<T> consumer) {
        Preconditions.checkArgument(Objects.nonNull(entity), "entity must supply");
        consumer.accept(this.entity);
        return this;
    }

    @Override
    public Optional<T> execute() {
        doValidate(this.entity, CreateGroup.class);
        T save = Try.of(() -> repository.save(entity))
                .onSuccess(successHook)
                .onFailure(errorHook)
                .getOrNull();
        return Optional.ofNullable(save);
    }

    @Override
    public Executor<T> successHook(Consumer<T> consumer) {
        this.successHook = consumer;
        return this;
    }

    @Override
    public Executor<T> errorHook(Consumer<? super Throwable> consumer) {
        this.errorHook = consumer;
        return this;
    }
}
